package cn.cdeden.knowledge.controller.schedule;

import cn.cdeden.common.core.domain.R;
import cn.cdeden.common.core.utils.page.TableDataInfo;
import cn.cdeden.common.satoken.utils.LoginHelper;
import cn.cdeden.knowledge.domain.*;
import cn.cdeden.knowledge.domain.dto.*;
import cn.cdeden.knowledge.domain.vo.SysScheduleVO;
import cn.cdeden.knowledge.service.*;
import cn.cdeden.knowledge.utils.BeanCopyUtil;
import cn.cdeden.system.api.RemoteUserService;
import cn.cdeden.system.api.domain.vo.RemoteUserVo;
import cn.cdeden.system.api.model.LoginUser;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.catalina.User;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * *作者：gjx
 * *日期：2024/7/11    10:20
 * *文件描述：
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/sys/schedule")
//@Api(tags = "日历相关接口")
public class SysScheduleController {

    @Autowired
    private SysScheduleService sysScheduleService;

    @Autowired
    private SysCalendarPersonnelService sysCalendarPersonnelService;

    @Autowired
    private SysUserPermissionsService sysUserPermissionsService;

    @Autowired
    private SysScheduleFollowService sysScheduleFollowService;

    @Autowired
    private SysAttentionUserService sysAttentionUserService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private SysSchedulePermissionsService sysSchedulePermissionsService;

    @Autowired
    private SysCalendarService sysCalendarService;

    @Autowired
    private SysCalendarSharingService sysCalendarSharingService;

    @Autowired
    private SysPermissionsRelevanceService sysPermissionsRelevanceService;


    @GetMapping("/all")
//    @Log("查询个人所有日历")
//    @ApiOperation("查询个人所有日历")
    public R<List<SysScheduleVO>> getAll(String scheduleName) {
        List<SysSchedule> sysScheduleList = new ArrayList<>();
        LoginUser user = LoginHelper.getLoginUser();
        //查询加入的日历
        List<SysCalendarPersonnel> sysCalendarPersonnelList = sysCalendarPersonnelService.list(new QueryWrapper<SysCalendarPersonnel>().eq("range_type", 0).eq("range_value", user.getUserId()));
        List<Long> scheduleIds = sysCalendarPersonnelList.stream().map(SysCalendarPersonnel::getScheduleId).collect(Collectors.toList());
        if (!scheduleIds.isEmpty()) {
            QueryWrapper<SysSchedule> sysScheduleQueryWrapper = new QueryWrapper<SysSchedule>();
            sysScheduleQueryWrapper.in("id", scheduleIds);
            if (scheduleName != null && !scheduleName.equals("")) {
                sysScheduleQueryWrapper.like("schedule_name", "%" + scheduleName + "%");
            }
            List<SysSchedule> sysSchedules = sysScheduleService.list(new QueryWrapper<SysSchedule>().in("id", scheduleIds));
            sysScheduleList.addAll(sysSchedules);
        }
        //查询权限是公开的日历
        QueryWrapper<SysSchedule> sysScheduleQueryWrapper = new QueryWrapper<>();
        sysScheduleQueryWrapper.eq("schedule_purview", 1);
        if (scheduleName != null && scheduleName != "") {
            sysScheduleQueryWrapper.like("schedule_name", "%" + scheduleName + "%");
        }
        List<SysSchedule> sysSchedules = sysScheduleService.list(new QueryWrapper<SysSchedule>().eq("schedule_purview", 1));
        sysScheduleList.addAll(sysSchedules);
        sysScheduleList = sysScheduleList.stream()
                .distinct()
                .sorted(Comparator.comparing(SysSchedule::getCreateTime))
                .collect(Collectors.toList());
        //显示日历关注状态
        List<Long> scheduleIdList = sysScheduleFollowService.list(new QueryWrapper<SysScheduleFollow>().eq("user_id", user.getUserId())).stream().map(SysScheduleFollow::getScheduleId).collect(Collectors.toList());
        List<SysScheduleVO> sysScheduleVOList = new ArrayList<>();
        sysScheduleList.forEach(v -> {
            SysScheduleVO sysScheduleVO = new SysScheduleVO();
            BeanCopyUtil.copyProperties(v, sysScheduleVO);
            if (scheduleIdList.contains(v.getId())) {
                sysScheduleVO.setCheck("true");
            }
            sysScheduleVOList.add(sysScheduleVO);
        });
        return R.ok(sysScheduleVOList);
    }

    @GetMapping("/get-personal-attention")
//    @Log("个人关注日历列表")
//    @ApiOperation("个人关注日历列表")
    public R<List<SysScheduleDto>> getPersonalAttention() {
        LoginUser user = LoginHelper.getLoginUser();
        List<SysScheduleDto> sysScheduleList = new ArrayList<>();
        List<SysScheduleFollow> sysScheduleFollowList = sysScheduleFollowService.list(new QueryWrapper<SysScheduleFollow>().eq("user_id", user.getUserId()));
        List<Long> scheduleIds = sysScheduleFollowList.stream().map(SysScheduleFollow::getScheduleId).collect(Collectors.toList());
        if (! scheduleIds.isEmpty()) {
            sysScheduleList = sysScheduleService.getAllAndPermission(scheduleIds, user.getUserId());
            sysScheduleList = sysScheduleList.stream()
                    .collect(Collectors.toMap(
                            SysScheduleDto::getId, // 使用 ID 作为键
                            dto -> dto,            // 使用对象本身作为值
                            (existing, replacement) -> {
                                // 如果有一个的 SysScheduleState 为 true，保留 true 的状态
                                if ("true".equals(replacement.getSysScheduleState())) {
                                    existing.setSysScheduleState("true");
                                }
                                return existing;
                            }))
                    .values().stream()
                    .collect(Collectors.toList());
        }
        return R.ok(sysScheduleList);
    }

    @PostMapping("/personal-attention-add")
//    @Log("新增个人日历关注")
//    @ApiOperation("新增个人日历关注")
    public R personalAttentionAdd(@RequestBody SysScheduleFollow sysScheduleFollow) {
        LoginUser user = LoginHelper.getLoginUser();
        sysScheduleFollow.setUserId(user.getUserId());
        return R.ok(sysScheduleFollowService.save(sysScheduleFollow));
    }

    @DeleteMapping("/personal-attention-delete")
//    @Log("删除个人日历关注")
//    @ApiOperation("删除个人日历关注")
    public R personalAttentionDelete(@RequestParam("scheduleId") Long scheduleId) {
        LoginUser user = LoginHelper.getLoginUser();
        return R.ok(sysScheduleFollowService.remove(new QueryWrapper<SysScheduleFollow>()
                .eq("user_id", user.getUserId())
                .eq("schedule_id", scheduleId)));
    }

    @PostMapping("/add")
//    @Log("新增日历")
//    @ApiOperation("新增日历")
    @Transactional(rollbackFor = Exception.class)
    public R add(@RequestBody SysScheduleDto sysScheduleDto) {
        LoginUser user = LoginHelper.getLoginUser();
        SysSchedule sysSchedule = new SysSchedule();
        BeanCopyUtil.copyProperties(sysScheduleDto, sysSchedule);
        sysSchedule.setCreateBy(user.getUserId());
        sysSchedule.setCreateTime(new Date());
        sysScheduleService.save(sysSchedule);
        //默认情况下新建的日历自动进入创建人员的关注列表
        SysScheduleFollow sysScheduleFollow = new SysScheduleFollow();
        sysScheduleFollow.setScheduleId(sysSchedule.getId());
        sysScheduleFollow.setUserId(user.getUserId());
        sysScheduleFollowService.save(sysScheduleFollow);
        if(sysSchedule.getSchedulePurview().equals(0)) {
            //添加关联表日历人员表
            List<SysCalendarPersonnel> sysCalendarPersonnelList = new ArrayList<>();
            sysScheduleDto.getUserIdList().forEach( v -> {
                SysCalendarPersonnel sysCalendarPersonnel = new SysCalendarPersonnel();
                sysCalendarPersonnel.setScheduleId(sysSchedule.getId());
                sysCalendarPersonnel.setRangeType(0);
                sysCalendarPersonnel.setRangeValue(v);
                sysCalendarPersonnelList.add(sysCalendarPersonnel);
            });
            sysCalendarPersonnelService.saveBatch(sysCalendarPersonnelList);
        } else {
            List<SysCalendarPersonnel> sysCalendarPersonnelList = new ArrayList<>();
            remoteUserService.selectListAll().forEach(v-> {
                SysCalendarPersonnel sysCalendarPersonnel = new SysCalendarPersonnel();
                sysCalendarPersonnel.setScheduleId(sysSchedule.getId());
                sysCalendarPersonnel.setRangeType(0);
                sysCalendarPersonnel.setRangeValue(v.getUserId());
                sysCalendarPersonnelList.add(sysCalendarPersonnel);
            });
            sysCalendarPersonnelService.saveBatch(sysCalendarPersonnelList);
        }
        //添加日历人员
        List<SysUserPermissions> sysUserPermissionsList = new ArrayList<>();
        if(sysSchedule.getSchedulePurview().equals(0)) {
            sysScheduleDto.getUserIdList().forEach( v -> {
                SysUserPermissions sysUserPermissions = new SysUserPermissions();
                sysUserPermissions.setScheduleId(sysSchedule.getId());
                sysUserPermissions.setUserId(v);
                sysUserPermissions.setPermissionsId(2l);
                if (v.equals(user.getUserId())) {
                    sysUserPermissions.setPermissionsId(1l);
                }
                sysUserPermissionsList.add(sysUserPermissions);
            });
            return R.ok(sysUserPermissionsService.saveBatch(sysUserPermissionsList));
        } else {
            //如果是公开的那么userIdList则为所有的人员
            sysScheduleDto.setUserIdList(remoteUserService.selectListAll().stream().map(RemoteUserVo::getUserId).collect(Collectors.toList()));
            sysScheduleDto.getUserIdList().forEach( v -> {
                SysUserPermissions sysUserPermissions = new SysUserPermissions();
                sysUserPermissions.setScheduleId(sysSchedule.getId());
                sysUserPermissions.setUserId(v);
                sysUserPermissions.setPermissionsId(sysScheduleDto.getPermissionsId());
                sysUserPermissionsList.add(sysUserPermissions);
            });
        }
        return R.ok(sysUserPermissionsService.saveBatch(sysUserPermissionsList));
    }


    @GetMapping("/edit")
//    @Log("修改日历回显所有数据")
//    @ApiOperation("修改日历回显所有数据")
    public R<SysScheduleDto> getEdit(@RequestParam Map<String, Object> params, Pageable pageable) {
        Long id = MapUtils.getLong(params, "id");
        LoginUser user = LoginHelper.getLoginUser();
        String userName = MapUtils.getString(params, "userName");
        Long permissionsId = MapUtils.getLong(params, "permissionsId");
        SysScheduleDto sysScheduleDto = new SysScheduleDto();
        SysSchedule sysSchedule = sysScheduleService.getById(id);
        BeanCopyUtil.copyProperties(sysSchedule, sysScheduleDto);
        //查询人员与权限
        TableDataInfo<UserAuthorityDto> userPermissions = sysUserPermissionsService.getUserPermissions(id, userName, permissionsId, pageable);
        sysScheduleDto.setUserAuthorityPage(userPermissions);
        sysScheduleDto.setUserAuthorityList(userPermissions.getRows());
        return R.ok(sysScheduleDto);
    }

    @PutMapping("/edit")
//    @Log("修改日历的基本信息")
//    @ApiOperation("修改日历的基本信息")
    @Transactional(rollbackFor = Exception.class)
    public R edit(@RequestBody ScheduleEditDto scheduleEditDto) {
        LoginUser user = LoginHelper.getLoginUser();
        List<Long> allAndDetails = sysScheduleService.getAllAndDetails(scheduleEditDto.getId(), user.getUserId());
        if (!allAndDetails.contains(1l) && !scheduleEditDto.getCreateBy().equals(user.getUserId())) {
            return R.fail("406", "你没有权限修改!");
        }
        SysSchedule sysSchedule = new SysSchedule();
        BeanCopyUtil.copyProperties(scheduleEditDto, sysSchedule);
        //
        if (scheduleEditDto.getSchedulePurview().equals(1)) {
            sysUserPermissionsService.remove(new QueryWrapper<SysUserPermissions>().eq("schedule_id", scheduleEditDto.getId()));
            //日历所有的人
            List<Long> userIds = sysCalendarPersonnelService.list(new QueryWrapper<SysCalendarPersonnel>().eq("schedule_id", scheduleEditDto.getId())).stream().map(SysCalendarPersonnel::getRangeValue).collect(Collectors.toList());
            List<SysUserPermissions> sysUserPermissionsList = new ArrayList<>();
            if (!userIds.isEmpty()) {
                userIds.forEach(v -> {
                    SysUserPermissions sysUserPermissions = new SysUserPermissions();
                    sysUserPermissions.setPermissionsId(scheduleEditDto.getPermissionsId());
                    sysUserPermissions.setUserId(v);
                    sysUserPermissions.setScheduleId(scheduleEditDto.getId());
                    sysUserPermissionsList.add(sysUserPermissions);
                });
            }
            sysUserPermissionsService.saveBatch(sysUserPermissionsList);
        }
        return R.ok(sysScheduleService.updateById(sysSchedule));
    }

    @PostMapping("/user-add")
//    @Log("日历成员添加成员")
//    @ApiOperation("日历成员添加成员")
    @Transactional
    public R add(@RequestBody SysUserPermissionsDto sysUserPermissionsDto) {
        List<SysCalendarPersonnel> sysCalendarPersonnelList = sysCalendarPersonnelService.list(new QueryWrapper<SysCalendarPersonnel>()
                .eq("schedule_id", sysUserPermissionsDto.getScheduleId()));
        List<Long> collect = sysCalendarPersonnelList.stream().map(SysCalendarPersonnel::getRangeValue).collect(Collectors.toList());
        sysUserPermissionsDto.getUserIds().removeAll(collect);
        LoginUser user = LoginHelper.getLoginUser();
        List<Long> allAndDetails = sysScheduleService.getAllAndDetails(sysUserPermissionsDto.getScheduleId(), user.getUserId());
        if (!allAndDetails.contains(1l)) {
            return R.fail("406","你没有权限添加成员!");
        }
        sysUserPermissionsDto.setPermissionsId(2l);
        //往日历人员中添加数据
        if (!sysUserPermissionsDto.getUserIds().isEmpty()) {
            sysCalendarPersonnelService.addByBatch(sysUserPermissionsDto);
        }


        //往日历人员权限中添加数据
        if (!sysUserPermissionsDto.getUserIds().isEmpty()) {
            sysUserPermissionsService.addByBatch(sysUserPermissionsDto);
        }
        return R.ok("sysUserPermissionsService.save(sysUserPermissionsDto)");
    }

    @PutMapping("/user-edit")
//    @Log("日历成员修改成员权限")
//    @ApiOperation("日历成员修改成员权限")
    public R editUser(@RequestBody SysUserPermissionsDto sysUserPermissionsDto) {
        LoginUser user = LoginHelper.getLoginUser();
        List<Long> allAndDetails = sysScheduleService.getAllAndDetails(sysUserPermissionsDto.getScheduleId(), user.getUserId());
        if (!allAndDetails.contains(1l)) {
            return R.fail("406","你没有权限修改成员权限!");
        }
        return R.ok(sysUserPermissionsService.updateBatchByScheduleId(sysUserPermissionsDto.getScheduleId(), sysUserPermissionsDto.getPermissionsId(), sysUserPermissionsDto.getUserIds()));
    }

    @DeleteMapping("/user-delete")
//    @Log("日历成员删除成员")
//    @ApiOperation("日历成员删除成员")
    @Transactional(rollbackFor = Exception.class)
    public R deleteUser(@RequestBody SysUserPermissionsDto sysUserPermissionsDto) {
        LoginUser user = LoginHelper.getLoginUser();
        List<Long> allAndDetails = sysScheduleService.getAllAndDetails(sysUserPermissionsDto.getScheduleId(), user.getUserId());
        if (!allAndDetails.contains(1l)) {
            return R.fail("406","你没有移除人员的权限!");
        }
        //删除日历日历个人关注表中的数据
        sysScheduleFollowService.remove(new QueryWrapper<SysScheduleFollow>().eq("schedule_id", sysUserPermissionsDto.getScheduleId()).in("user_id", sysUserPermissionsDto.getUserIds()));
        //删除日历日历人员表中的数据
        sysScheduleService.deleteBatchPersonnel(sysUserPermissionsDto.getScheduleId(), sysUserPermissionsDto.getUserIds());
        //删除日历中的成员的同时也要删除日程中对应的成员
        List<SysCalendar> sysCalendars = sysCalendarService.list(new QueryWrapper<SysCalendar>().eq("schedule_id", sysUserPermissionsDto.getScheduleId()));
        List<Long> calendarIds = sysCalendars.stream().map(SysCalendar::getId).collect(Collectors.toList());
        List<SysCalendarSharing> sysCalendarSharingList = new ArrayList<>();
        if (!calendarIds.isEmpty()) {
            sysCalendarSharingList = sysCalendarSharingService.list(new QueryWrapper<SysCalendarSharing>().in("calendar_id", calendarIds));
            sysCalendarSharingList.forEach(sysCalendarSharing -> {
                List<Long> userIdList = JSONUtil.toList(sysCalendarSharing.getCalendarSharingId(), Long.class);
                userIdList.removeAll(sysUserPermissionsDto.getUserIds());
                sysCalendarSharing.setCalendarSharingId(new JSONArray(userIdList).toString());
            });
        }
        sysCalendarSharingService.updateBatchById(sysCalendarSharingList);

        //删除日历人员权限表中的数据
        return R.ok(sysScheduleService.deleteBatchPermissions(sysUserPermissionsDto.getScheduleId(), sysUserPermissionsDto.getUserIds()));
    }

    @DeleteMapping("/delete/{id}")
//    @Log("删除日历")
//    @ApiOperation("删除日历")
    @Transactional(rollbackFor = Exception.class)
    public R delete(@PathVariable Long id) {
        LoginUser user = LoginHelper.getLoginUser();
        SysUserPermissions sysUserPermissions = sysUserPermissionsService.getOne(new QueryWrapper<SysUserPermissions>().eq("user_id", user.getUserId()).eq("schedule_id", id));
        List<SysPermissionsRelevance> sysPermissionsRelevances = sysPermissionsRelevanceService.list(new QueryWrapper<SysPermissionsRelevance>().eq("permissions_id", sysUserPermissions.getPermissionsId()));
        List<Long> permissionsIdList = sysPermissionsRelevances.stream().map(SysPermissionsRelevance::getPermissionsId).collect(Collectors.toList());
        if (!permissionsIdList.contains(1l)) {
            return R.fail("406","你没有权限删除日历!");
        }
        boolean b = sysScheduleService.removeById(id);
        boolean removeSchedule = sysCalendarService.remove(new QueryWrapper<SysCalendar>().eq("schedule_id", id));
        boolean removeScheduleFollow = sysScheduleFollowService.remove(new QueryWrapper<SysScheduleFollow>().eq("schedule_id", id));
        return  R.ok("删除日历成功");
    }

    @GetMapping("/get-attention-all")
//    @Log("查询成员关注表中的成员")
//    @ApiOperation("查询成员关注表中的成员")
    public R<List<RemoteUserVo>> getAttentionAll() {
        LoginUser user = LoginHelper.getLoginUser();
        List<Long> userIds = sysAttentionUserService.list(new QueryWrapper<SysAttentionUser>().eq("user_id", user.getUserId()))
                .stream()
                .map(SysAttentionUser::getAttentionUserId)
                .collect(Collectors.toList());
        List<RemoteUserVo> userList = new ArrayList<>();
        if (!userIds.isEmpty()) {
            userList = remoteUserService.selectListByIds(userIds);
        }
        return R.ok(userList);
    }

    @PostMapping("/add-attention")
//    @Log("增加成员关注表中成员")
//    @ApiOperation("增加成员关注表中成员")
    public R addAttention(@RequestBody SysAttentionUserDto sysAttentionUserDto) {
        LoginUser user = LoginHelper.getLoginUser();
        sysAttentionUserDto.setUserId(user.getUserId());
        boolean remove = sysAttentionUserService.remove(new QueryWrapper<SysAttentionUser>().eq("user_id", user.getUserId()));
        return R.ok(sysAttentionUserService.saveByBatch(sysAttentionUserDto));
    }

    @DeleteMapping("/delete-attention")
//    @Log("删除成员关注表中的成员")
//    @ApiOperation("删除成员关注表中的成员")
    public R deleteAttention(@RequestParam("attentionUserId") Long attentionUserId) {
        LoginUser user = LoginHelper.getLoginUser();
        return R.ok(sysAttentionUserService.remove(new QueryWrapper<SysAttentionUser>().eq("attention_user_id", attentionUserId).eq("user_id", user.getUserId())));
    }


    @PostMapping("/attention-show")
//    @Log("查询关注成员的日程数据")
//    @ApiOperation("查询关注成员的日程数据")
    public R<List<SysCalendarDto>> attentionShow(@RequestBody CalendarDTO calendarDTO) {
        return R.ok(sysScheduleService.attentionShow(calendarDTO.getUserIds(), calendarDTO.getStartDate(), calendarDTO.getEndDate()));
    }

    @GetMapping("/get-permissions")
//    @Log("查询所有权限")
//    @ApiOperation("查询所有权限")
    public R<List<SysSchedulePermissions>> getPermissions() {
        return R.ok(sysSchedulePermissionsService.list());
    }

}
